package com.qf.shopping.servlet.backController;

import com.qf.shopping.common.Constants;
import com.qf.shopping.common.DisatpcherServlet;
import com.qf.shopping.entity.Page;
import com.qf.shopping.entity.Product;
import com.qf.shopping.service.IProductService;
import com.qf.shopping.service.impl.ProductServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**处理与商品相关的请求
 * @author 三旬
 * @version 1.0  2022/9/18
 */
@WebServlet("/ProductController/*")
public class ProductController extends DisatpcherServlet {
    //1.创建访问业务层的接口
    IProductService productService = new ProductServiceImpl();
    //2.实现访问的方法

    /**
     * 分页显示上架的商品
     * @param request
     * @param response
     * @return
     */
    public String selectPage(HttpServletRequest request, HttpServletResponse response){
        //获得前端的请求页面
        String index = request.getParameter("index");
        String size = request.getParameter("size");
        //封装数据
        Page<Product> page = new Page<>();
        if(index != null && !"".equals(index)){
            page.setIndex(Integer.valueOf(index));
        }
        if(size != null && !"".equals(size)){
            page.setSize(Integer.valueOf(size));
        }
        //设置请求的上文路径
        page.setUrl("ProductController/selectPage");
        //发送请求给业务层处理
        productService.selectPage(page);
        //把page对象添加到作用域中
        request.setAttribute("page",page);
        //转发到用户列表展示数据
        return Constants.FORWARD+":back/goods/goodsList.jsp";

    }

    /**
     * 添加商品
     * @param request
     * @param response
     * @return
     */
    public String addProduct(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //解析表单的数据,返回一个商品对象
        Product product = parseForm(request);
        //调用业务层添加商品
        Boolean result = productService.add(product);
        //根据结果响应
        if (result) {
            return Constants.REDIRECT+":ProductController/selectPage";
        }
        return Constants.SCRIPT+":添加失败！";
    }

    /**
     * 解析表单的数据（读取表单中含有图片、文件等，二进制文件）
     * @param request
     * @return
     */
    private Product parseForm(HttpServletRequest request) throws Exception {
        //  将请求消息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现) 对象的任务
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //创建一个上传工具，指定使用缓存区与临时文件存储位置
        ServletFileUpload upload =new ServletFileUpload(factory);
        //解析request对象,得到所有上传项，每一个FileItem就相当与一个上传项
        // fileImte:代表的就是表单中的一个元素,表单有多个元素就用list来转
        // list就当成表单中的数据，表单中的数据全部在这个list中
        List<FileItem> list = upload.parseRequest(request);
        //创建一个map读取数据
        Map<String,Object> map = new HashMap<>();
        for (FileItem item : list) {
            // 判断当前fileItem是否是文本元素
            if(item.isFormField()){
                // 表单的name属性实现
                String name = item.getFieldName();
                // 表单文本的value可以通过这种方式来获取数据，同时设置编码格式
                String value = item.getString("utf-8");
                // 把表单数据放到Map中
                map.put(name, value);
            }else{
                FileOutputStream os = null;
                try {
                    // 二进制文件的解析
                    //1.获得上传文件的名称
                    String fileName = item.getName();
                    if(fileName != null && !"".equals(fileName)){
                        //表单的name属性
                        String name = item.getFieldName();
                        //2.定义文件输出的位置
                        //获得文件再服务器的存放位置
//                    String serverName = request.getServerName();//主机地址
//                    int port = request.getServerPort();//端口号
//                String path = serverName +":"+ port+"/images/download/" ;//文件的下载位置
                        String realPath = request.getSession().getServletContext().getRealPath("/");
                        File file = new File(realPath+"images/"+fileName);
                        System.out.println(file);
                        // 设置把用户上传的文件写入到的目录
                        os = new FileOutputStream(file);
                        // 3.把用户上传的文件，拷贝到输出流上去
                        IOUtils.copy(item.getInputStream(), os); // IO流拷贝到指定位置
                        // 4.把文件写入到服务器后，需要把文件的地址写入到Map中
                        map.put(name, fileName);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if (os != null){
                        os.close();
                    }
                }
            }
        }
        //读取map集合，创建一个Product对象
        // 把Map中的数据拷贝到实体类中， Map中的key要和实体类中的实现一致
        Product product = new Product();
        BeanUtils.populate(product, map);
        System.out.println(product);
        return product;
    }

    /**
     * 删除商品信息
     * @param request
     * @param response
     * @return
     */
    public String deleteProductById(HttpServletRequest request, HttpServletResponse response){
        //接收要删除的商品信息
        Integer id = Integer.valueOf(request.getParameter("id"));
        //调用业务层处理
        //1.先将服务器端的图片删除（需要获得图片的名称，再次调用该对象）
        //获得web的根路径
        String realPath = request.getSession().getServletContext().getRealPath("/");
        Boolean result1 = productService.delProductPngById(id,realPath);
        //删除数据库中的信息
        Boolean result2 = productService.deleteById(id);
//        File file = new File(realPath+"images/download/"+fileName);
        if (result1 && result2) {
            return Constants.REDIRECT+":ProductController/selectPage";
        }
        return Constants.SCRIPT+":"+"删除失败！";
    }

    /**
     * 编辑商品信息，需要回填信息
     * @param request
     * @param response
     * @return
     */
    public String getProductById(HttpServletRequest request, HttpServletResponse response){
        //获得编辑商品的id
        Integer id = Integer.valueOf(request.getParameter("id"));
        //调用业务层处理
        Product product = productService.selectOneById(id);
        //将商品信息放到request作用域中
        request.setAttribute("product",product);
        //转发响应到修改的jsp页面
        return Constants.FORWARD+":back/goods/goodupdate.jsp";
    }

    /**
     * 更新商品信息
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public String updateProduct(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //接收前端的数据,需要解析二进制文件
        Product product = parseForm(request);
        //判断前端是否对图片有所更改
        if(product.getPngUrl() == null || "".equals(product.getPngUrl())){
            //图片没有更改，调用业务层处理
            boolean result = productService.updateNoPngById(product);
            //根据结果判断响应
            if (result){
                return Constants.REDIRECT+":ProductController/selectPage";
            }
        }else{
            //图片更改了，需要删除之前的图片缓存
            //获得图片的存放路径, web的根路径
            Integer id = product.getId();
            String realPath = request.getSession().getServletContext().getRealPath("/");
            //删除旧的图片
            boolean result1 = productService.delProductPngById(id,realPath);
            //将修改后的商品信息写入数据库
            boolean result2 = productService.updateById(product);
            if (result1 && result2){
                return Constants.REDIRECT+":ProductController/selectPage";
            }
        }
        return Constants.SCRIPT+":"+"修改失败！";
    }

    public String a(HttpServletRequest request, HttpServletResponse response){
        return null;
    }





}
